﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CSharp.Libs.ExceptionHandling;
using CSharp.Libs.Koc;
using CSharp.Libs.Misc;
using CSharp.Libs.Net;
using CSharp.Libs.WPF;
using System.Windows.Input;
using System.Collections;
using System.Collections.ObjectModel;



namespace KocAllianceLister
{
    class KocAllianceList : ViewModelBase
    {
        #region declarations
        private ExceptionCollector _EC = null;
        private URLHolder _UH = null;

        private RelayCommand _rcGotoPage = null;
        private RelayCommand _rcNextPage = null;
        private RelayCommand _rcPreviousPage = null;

        private ObservableCollection<KocAllianceListItem> _ocOtherAlliances = new ObservableCollection<KocAllianceListItem>();

        private String _strUrl = "";
        private String _strResult = "";
        private String _strNoOfPages = "";
        private String _strCurrentPage = "";

        #region constants
        private const String DATE_TIME_STAMP_MASK =         "dd.MM.yyyy HH:mm:ss";

        private const String PARAM_PAGE_NO =                "pageNo";

        private const String KEY_OK =                       "ok";
        private const String KEY_CURRENT_PAGE =             "currentPage";
        private const String KEY_NO_OF_PAGES =              "noOfPages";
        private const String KEY_OTHER_ALLIANCES =          "otherAlliances";
        private const String KEY_ALLIANCE_ID =              "allianceId";
        private const String KEY_NAME =                     "name";
        private const String KEY_MEMBERS_COUNT =            "membersCount";
        private const String KEY_MIGHT =                    "might";
        private const String KEY_RANKING =                  "ranking";
        private const String KEY_HOST_USER_ID =             "hostUserId";
        private const String KEY_HOST =                     "host";
        private const String KEY_HOST_GENDER_AND_NAME =     "hostGenderAndName";
        private const String KEY_FOUNDER_USER_ID =          "founderUserId";
        private const String KEY_FOUNDER_NAME =             "founderName";
        private const String KEY_FOUNDER_GENDER_AND_NAME =  "founderGenderAndName";
        #endregion
        #endregion



        #region constructor / terminator
        public KocAllianceList(
            ExceptionCollector EC,
            URLHolder UH)
        {
            _EC = EC;
            _UH = UH;
        }

        ~KocAllianceList()
        {
            _UH = null;
            _EC = null;
        }
        #endregion



        #region private functions
        private void _SetUrl()
        {
            try
            {
                _UH.ParseURLAllianceGetOtherInfo(_strUrl);

                _ExecuteURL();
                
                OnPropertyChanged("Url");
                OnPropertyChanged("UrlValidness");
                OnPropertyChanged("PageNo");
            }
            catch(Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }
        }

        private void _RefreshURL()
        {
            try
            {
                _strUrl = _UH.URLAllianceGetOtherInfo.GetURL();
                OnPropertyChanged("Url");
                OnPropertyChanged("UrlValidness");
            }
            catch(Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }
        }

        private void _ResetResult()
        {
            try
            {
                _strResult = "";
                OnPropertyChanged("Result");
            }
            catch(Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }
        }

        private void _ExecuteURL()
        {
            try
            {
                if(_UH.URLAllianceGetOtherInfo.URLMaybeValid)
                {
                    _ocOtherAlliances.Clear();

                    Hashtable htResult = null;
                    if(_UH.URLAllianceGetOtherInfo.GetAnswerHashtable(out htResult))
                    {
                        Boolean fResultOk = false;
                        Boolean.TryParse(htResult[KEY_OK].ToString(), out fResultOk);
                        if(fResultOk)
                        {
                            _strNoOfPages = htResult[KEY_NO_OF_PAGES].ToString();
                            OnPropertyChanged("NoOfPages");
                            _strCurrentPage = htResult[KEY_CURRENT_PAGE].ToString();
                            OnPropertyChanged("CurrentPage");

                            ArrayList _aryOtherAlliances = htResult[KEY_OTHER_ALLIANCES] as ArrayList;
                            if (_aryOtherAlliances != null)
                            {
                                foreach(Hashtable HT in _aryOtherAlliances)
                                {
                                    try
                                    {
                                        KocAllianceListItem KALI=new KocAllianceListItem();
                                        KALI.AllianceId =           HT[KEY_ALLIANCE_ID].ToString();
                                        KALI.Name =                 HT[KEY_NAME].ToString();
                                        KALI.MembersCount =         HT[KEY_MEMBERS_COUNT].ToString();
                                        KALI.Might =                Int32.Parse(HT[KEY_MIGHT].ToString()).ToString("0,000");
                                        KALI.Ranking =              HT[KEY_RANKING].ToString();
                                        KALI.HostUserId =           HT[KEY_HOST_USER_ID].ToString();
                                        KALI.Host =                 HT[KEY_HOST].ToString();
                                        KALI.HostGenderAndName =    HT[KEY_HOST_GENDER_AND_NAME].ToString();
                                        KALI.FounderUserId =        HT[KEY_FOUNDER_USER_ID].ToString();
                                        KALI.FounderName =          HT[KEY_FOUNDER_NAME].ToString();
                                        KALI.FounderGenderAndName = HT[KEY_FOUNDER_GENDER_AND_NAME].ToString();
                                        _ocOtherAlliances.Add(KALI);
                                    }
                                    catch(Exception ex)
                                    {
                                        _strResult = String.Concat(_strResult, "Error putting ListItem in ObservableCollection.", Environment.NewLine);
                                        _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
                                    }
                                }
                            }
                            else
                            {
                                _strResult = "Server didn't return ArrayList.";
                            }
                        }
                        else
                        {
                            _strResult = "Server returned false.";
                        }
                    }
                    else
                    {
                        _strResult = "Execute didn't return true.";
                    }
                }
                else
                {
                    _strResult = "URL is not valid.";
                }

                OnPropertyChanged("Result");
                OnPropertyChanged("OtherAlliances");
            }
            catch(Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }
        }

        private void _GotoPage()
        {
            try
            {
                if (_UH.URLAllianceGetOtherInfo.URLMaybeValid)
                {
                    if (_UH.URLAllianceGetOtherInfo.Parameters[PARAM_PAGE_NO].ToString() != _strCurrentPage)
                    {
                        _ExecuteURL();
                    }
                }
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }
        }

        private void _NextPage()
        {
            try
            {
                if (_UH.URLAllianceGetOtherInfo.URLMaybeValid)
                {
                    Int32 intPageNo = 0;
                    Int32 intNoOfPages=0;
                    if (Int32.TryParse(_UH.URLAllianceGetOtherInfo.Parameters[PARAM_PAGE_NO].ToString(), out intPageNo) &&
                        Int32.TryParse(_strNoOfPages, out intNoOfPages))
                    {
                        if (intPageNo == intNoOfPages)
                        {
                            _UH.URLAllianceGetOtherInfo.Parameters[PARAM_PAGE_NO] = "1";
                            _ExecuteURL();
                        }
                        else
                        {
                            intPageNo++;
                            _UH.URLAllianceGetOtherInfo.Parameters[PARAM_PAGE_NO] = intPageNo.ToString();
                            _ExecuteURL();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }
        }

        private void _PreviousPage()
        {
            try
            {
                if (_UH.URLAllianceGetOtherInfo.URLMaybeValid)
                {
                    Int32 intPageNo = 0;
                    if (Int32.TryParse(_UH.URLAllianceGetOtherInfo.Parameters[PARAM_PAGE_NO].ToString(), out intPageNo))
                    {
                        if (intPageNo == 1)
                        {
                            _UH.URLAllianceGetOtherInfo.Parameters[PARAM_PAGE_NO] = _strNoOfPages;
                            _ExecuteURL();
                        }
                        else
                        {
                            intPageNo--;
                            _UH.URLAllianceGetOtherInfo.Parameters[PARAM_PAGE_NO] = intPageNo.ToString();
                            _ExecuteURL();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }
        }
        #endregion



        #region interface
        #region properties
        public String Url
        {
            get
            {
                return _strUrl;
            }
            set
            {
                _strUrl = value;
                _SetUrl();
            }
        }

        public String UrlValidness
        {
            get
            {
                if(_UH.URLAllianceGetOtherInfo.URLMaybeValid)
                {
                    return "OK";
                }
                else
                {
                    return "FALSE";
                }
            }
        }

        public ICommand GotoPage
        {
            get
            {
                if (_rcGotoPage == null)
                {
                    _rcGotoPage = new RelayCommand(
                        param => this._GotoPage(),
                        param => this.CanGotoPage);
                }
                return _rcGotoPage;
            }
        }
        public Boolean CanGotoPage
        {
            get
            {
                return _UH.URLAllianceGetOtherInfo.URLMaybeValid;
            }
        }

        public ICommand NextPage
        {
            get
            {
                if (_rcNextPage == null)
                {
                    _rcNextPage = new RelayCommand(
                        param => this._NextPage(),
                        param => this.CanNextPage);
                }
                return _rcNextPage;
            }
        }
        public Boolean CanNextPage
        {
            get
            {
                return _UH.URLAllianceGetOtherInfo.URLMaybeValid;
            }
        }

        public ICommand PreviousPage
        {
            get
            {
                if (_rcPreviousPage == null)
                {
                    _rcPreviousPage = new RelayCommand(
                        param => this._PreviousPage(),
                        param => this.CanPreviousPage);
                }
                return _rcPreviousPage;
            }
        }
        public Boolean CanPreviousPage
        {
            get
            {
                return _UH.URLAllianceGetOtherInfo.URLMaybeValid;
            }
        }
        
        public String Result
        {
            get
            {
                return _strResult;
            }
        }

        public String PageNo
        {
            get
            {
                if (_UH.URLAllianceGetOtherInfo.URLMaybeValid)
                {
                    return _UH.URLAllianceGetOtherInfo.Parameters[PARAM_PAGE_NO].ToString();
                }
                else
                {
                    return "";
                }
            }
            set
            {
                if (_UH.URLAllianceGetOtherInfo.URLMaybeValid)
                {
                    Int32 intPageNo = -1;
                    if (Int32.TryParse(value, out intPageNo))
                    {
                        if (intPageNo > 0)
                        {
                            _UH.URLAllianceGetOtherInfo.Parameters[PARAM_PAGE_NO] = value;
                        }
                    }
                }
            }
        }

        public String NoOfPages
        {
            get
            {
                return _strNoOfPages;
            }
        }

        public String CurrentPage
        {
            get
            {
                return _strCurrentPage;
            }
        }

        public ObservableCollection<KocAllianceListItem> OtherAlliances
        {
            get
            {
                return _ocOtherAlliances;
            }
        }
        #endregion

        #region methods
        #endregion
        #endregion
    }
}
